package com.fsoft.core.utils;

import java.io.BufferedReader;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.net.MalformedURLException;
import java.net.URL;
import java.util.ArrayList;
import java.util.List;
import java.util.regex.Pattern;

import javax.servlet.ServletContext;
import javax.servlet.ServletRequest;
import javax.servlet.http.HttpServletRequest;

import org.apache.commons.io.FileUtils;
import org.apache.commons.lang3.StringUtils;
import org.apache.shiro.SecurityUtils;
import org.apache.shiro.web.subject.WebSubject;
import org.springframework.web.context.WebApplicationContext;

import com.fsoft.core.context.FSContext;

public class FileManager {
	/**
	 * 文件路径的分隔符 目前使用linux的分隔符号 '/', 由于windows可以识别Linux的分隔符
	 */
	public static String SEPARATOR = "/";
	public static String WIN_SEPARATOR = "\\";
	public static String[] SEPARATORS = new String[] { FileManager.SEPARATOR, File.separator };
	/** config.properties 配置的目录 */
	private static File workSpace;
	private static File uploadSpace;
	private static File expSpace;
	private static File impSpace;
	private static File tempSpace;
	/**
	 * 读取zip的内部文件的最大限制 20M
	 */
	public static int MAX_ZIE_READ_FILE_SIZE = 1024 * 1024 * 20;

	public static String getRootPath() {
		String classPath = Thread.currentThread().getContextClassLoader().getResource("/").getPath();
		String rootPath = "";
		rootPath = classPath.substring(0, classPath.indexOf("/WEB-INF/classes"));
		rootPath = formatWebPath(rootPath);
		return rootPath;
	}

	/**
	 * 格式化web路径
	 * @author licheng
	 * @date 2021-04-11
	 * @param path
	 * @return
	 */
	public static String formatWebPath(String path) {
		if (StringUtils.endsWithAny(path, SEPARATORS)) {
			path = path.replace("/$", "");
			path = path.replace("\\\\$", "");
		}
		return path.replace("\\", "/").replace("\\\\", "//");
	}

	public static Boolean fileExists(String filename) {
		File file = new File(filename);
		return file.exists();
	}

	/**
	 * 获取目录下的所有文件包含子目录
	 * 
	 * @author gk @date 2017-8-3 下午3:03:16
	 * @param dir 目录
	 * @param filtes .java 获取扩展名是java的文件 ;*.* 所有文件
	 * @return
	 * @throws Exception
	 */
	public static ArrayList<File> getFiles(String dir, String filtes) throws Exception {
		Pattern pan = Pattern.compile(filtes);
		// 目标集合fileList
		ArrayList<File> fileList = new ArrayList<File>();
		File file = new File(dir);
		if (file.isDirectory()) {
			File[] files = file.listFiles();
			if (files == null) {
				return fileList;
			}
			for (File f : files) {
				// 如果这个文件是目录，则进行递归搜索
				if (f.isDirectory()) {
					fileList.addAll(getFiles(f.getPath(), filtes));
				} else {
					// 如果文件是普通文件，则将文件句柄放入集合中
					if (filtes.equalsIgnoreCase("*.*")) {
						fileList.add(f);
					} else if (pan.matcher(f.getName()).find()) {
						fileList.add(f);
					}
				}
			}
		}
		return fileList;
	}

	/**
	 * 递归取到当前目录所有文件
	 * 
	 * @param dir
	 * @return
	 */
	public static ArrayList<String> getFilePaths(String dir, String filtes) throws Exception {
		Pattern pan = Pattern.compile(filtes);
		// 目标集合fileList
		ArrayList<String> fileList = new ArrayList<String>();
		File file = new File(dir);
		if (file.isDirectory()) {
			File[] files = file.listFiles();
			if (files == null) {
				return fileList;
			}
			for (File f : files) {
				// 如果这个文件是目录，则进行递归搜索
				if (f.isDirectory()) {
					fileList.addAll(getFilePaths(f.getPath(), filtes));
				} else {
					// 如果文件是普通文件，则将文件句柄放入集合中
					if (filtes.equalsIgnoreCase("*.*")) {
						fileList.add(f.getPath());
					} else if (pan.matcher(f.getName()).find()) {
						fileList.add(f.getPath());
					}
				}
			}
		}
		return fileList;
	}

	/**
	 * 读取文件内的所有内容到字符串内
	 * 
	 * @author gk @date 2017-12-24 下午4:12:09
	 * @param sPath
	 * @return
	 * @throws IOException
	 */
	public static String readFileContent(String sPath) throws IOException {
		File file = new File(sPath);
		return readFileContent(file);
	}

	/**
	 * 读取文件内的所有内容到字符串内
	 * 
	 * @author gk @date 2017-12-24 下午4:12:09
	 * @param file
	 * @return
	 * @throws IOException
	 */
	public static String readFileContent(File file) throws IOException {
		return readFileContent(new FileInputStream(file));
	}

	/**
	 * 读取文件内的所有内容到字符串内
	 * 
	 * @author gk @date 2017-12-24 下午4:12:09
	 * @param in
	 * @return
	 * @throws IOException
	 */
	public static String readFileContent(InputStream in) throws IOException {
		InputStreamReader isr = new InputStreamReader(in, "UTF-8");
		BufferedReader bReader = new BufferedReader(isr);
		StringBuilder sb = new StringBuilder();
		String s = "";
		while ((s = bReader.readLine()) != null) {
			sb.append(s + "\n");
		}
		bReader.close();
		return sb.toString();
	}

	/**
	 * 读取文件内的所有内容到BufferedReader
	 * 
	 * @author gk @date 2017-12-24 下午4:12:09
	 * @param in
	 * @return
	 * @throws IOException
	 */
	public static BufferedReader readFileContentReader(InputStream in) throws IOException {
		InputStreamReader isr = new InputStreamReader(in, "UTF-8");
		BufferedReader bReader = new BufferedReader(isr);
		return bReader;
	}

	/**
	 * 删除单个文件
	 * 
	 * @param sPath 被删除文件的文件名
	 * @return 单个文件删除成功返回true，否则返回false
	 */
	public static Boolean deleteFile(String sPath) {
		File file = new File(sPath);
		Boolean ret = false;
		// 路径为文件且不为空则进行删除
		if (file.isFile() && file.exists()) {
			ret = file.delete();

		}
		return ret;
	}

	/**
	 * 创建文件,目录不存在也能创建
	 * 
	 * @author gk @date 2017-10-21 下午4:01:38
	 * @param destFileName
	 * @return
	 * @throws IOException
	 */
	public static File createFile(String destFileName) throws IOException {
		File file = new File(destFileName);
		return createFile(file);
	}

	/**
	 * 
	 * @author gk @date 2018年9月19日 下午3:11:38
	 * @param destFileName
	 * @param filecontent
	 * @return
	 * @throws IOException
	 */
	public static String createFileAndWrite(String destFileName, String filecontent) throws IOException {
		File file = new File(destFileName);
		createFile(file);
		writeFileContent(destFileName, filecontent);
		return file.getPath();
	}

	/**
	 * 创建文件写入内容，如果文件存在追加内容
	 * 
	 * @param destFileName
	 * @param filecontent
	 * @return
	 * @throws IOException
	 * @author qjb
	 * @date 2019年10月12日 下午2:52:19
	 */
	public static String createFileAndWriteAdd(String destFileName, String filecontent) throws IOException {
		File file = new File(destFileName);
		createFile(file);
		writeFileContentAdd(file, filecontent);
		return file.getPath();
	}

	/**
	 * 写入文件内容
	 * 
	 * @author gk @date 2018年9月19日 下午3:21:26
	 * @param filepath 文件路径
	 * @param filecontent 文件内容
	 * @return
	 * @throws IOException
	 */
	public static boolean writeFileContent(String filepath, String filecontent) throws IOException {
		boolean ret = false;
		File file = new File(filepath);
		writeFileContent(file, filecontent);
		return ret;
	}

	/**
	 * 文件写入内容
	 * 
	 * @author gk @date 2018年9月19日 下午3:22:22
	 * @param file 文件对象
	 * @param filecontent
	 * @return
	 * @throws IOException
	 */
	public static boolean writeFileContent(File file, String filecontent) throws IOException {
		boolean ret = false;
		FileOutputStream fos = null;
		try {
			fos = new FileOutputStream(file);
			fos.write(filecontent.getBytes());
		} finally {
			if (fos != null) {
				fos.close();
			}
		}
		return ret;
	}

	/**
	 * 文件追加写入内容
	 * 
	 * @param file
	 * @param filecontent
	 * @return
	 * @throws IOException
	 * @author qjb
	 * @date 2019年10月12日 下午2:47:10
	 */
	public static boolean writeFileContentAdd(File file, String filecontent) throws IOException {
		boolean ret = false;
		FileOutputStream fos = null;
		try {
			fos = new FileOutputStream(file, true);
			fos.write(filecontent.getBytes());
		} finally {
			if (fos != null) {
				fos.close();
			}
		}
		return ret;
	}

	/**
	 * 创建文件,目录不存在也能创建
	 * 
	 * @author gk @date 2017-10-21 下午4:03:50
	 * @param file
	 * @return
	 * @throws IOException
	 */
	public static File createFile(File file) throws IOException {
		if (file.exists()) {
			return file;
		}
		// 判断全
		if (file.isDirectory()) {
			throw new IOException("创建文件[" + file.getCanonicalPath() + "]不能是目录");
		}
		// 判断目标文件所在的目录是否存在
		if (!file.getParentFile().exists()) {
			// 如果目标文件所在的目录不存在，则创建父目录
			if (!file.getParentFile().mkdirs()) {
				return null;
			}
		}
		// 创建目标文件
		return file;
	}

	/***
	 * 在指定目录查找文件，找到则返回文件，否则返回null
	 * 
	 * @author licheng
	 * @date 2019-01-14
	 * @param workSpace
	 * @param fileName
	 * @return
	 * @throws IOException
	 */
	public static File getFile(File workSpace, String fileName) throws IOException {
		File f = new File(workSpace, fileName);
		if (f.exists() && f.isFile()) {
			return f;
		}
		return null;
	}

	/**
	 * 根据路径删除指定的目录或文件，无论存在与否
	 * 
	 * @param sPath 要删除的目录或文件
	 * @return 删除成功返回 true，否则返回 false。
	 */
	public static void deleteFolder(String sPath) {
		File file = new File(sPath);
		// 判断目录或文件是否存在
		// 不存在返回 false
		if (file.exists()) {
			// 判断是否为文件
			if (file.isFile()) {
				// 为文件时调用删除文件方法
				deleteFile(sPath);
			} else {
				// 为目录时调用删除目录方法
				deleteDirectory(sPath);
			}
		}
	}

	/**
	 * 创建目录,多级创建
	 * 
	 * @author gk @date 2017-10-21 下午4:04:10
	 * @param destDirName
	 * @return
	 * @throws IOException
	 */
	public static File createDir(String destDirName) throws IOException {
		File dir = new File(destDirName);
		return createDir(dir);
	}

	/**
	 * 创建目录 ,多级创建
	 * 
	 * @author gk @date 2018年11月5日 下午3:22:54
	 * @param dir
	 * @return
	 * @throws IOException
	 */
	public static File createDir(File dir) throws IOException {
		if (dir.exists()) {
			return dir;
		}
		// true if and only if the file denoted by this abstract pathname exists and is a directory;
		/*
		 * if (!dir.isDirectory()) { throw new IOException("路径[" + dir.getPath() + "]不是目录"); }
		 */
		// 创建目录
		if (dir.mkdirs()) {
			return dir;
		} else {
			return dir;
		}
	}

	/***
	 * 获取路径的分割符号
	 * 
	 * @author gk @date 2019年6月4日 上午11:59:25
	 * @param path
	 * @return
	 */
	public static String getPathSeparator(String path) {
		if (path.indexOf(SEPARATOR) >= 0) {
			return SEPARATOR;
		}
		if (path.indexOf(WIN_SEPARATOR) >= 0) {
			return WIN_SEPARATOR;
		}
		return SEPARATOR;
	}

	/**
	 * 获取路径的目录 c:/dir1/dir2/file1.txt => c:/dir1/dir2/
	 * 
	 * @author gk @date 2017-10-20 上午9:42:46
	 * @param fullFilePath
	 * @return
	 */
	public static String extractPath(String fullFilePath) {
		String pathSeparator = getPathSeparator(fullFilePath);
		return fullFilePath.substring(0, fullFilePath.lastIndexOf(pathSeparator) + 1);
	}

	/**
	 * 获取路径的文件名包含扩展名 c:/dir1/dir2/file1.txt => file1.txt
	 * 
	 * @author gk @date 2017-10-20 上午9:42:31
	 * @param fullFilePath
	 * @return
	 */
	public static String extractFileNameWithExt(String fullFilePath) {
		String pathSeparator = getPathSeparator(fullFilePath);
		return fullFilePath.substring(fullFilePath.lastIndexOf(pathSeparator) + 1, fullFilePath.length());
	}

	/**
	 * 获取路径的文件名不包含路径不包含扩展名 c:/dir1/dir2/file1.txt => file1
	 * 
	 * @author gk @date 2017-10-20 上午9:42:31
	 * @param fullFilePath
	 * @return
	 */
	public static String extractFileNameWithNoExt(String fullFilePath) {
		String fileName = extractFileNameWithExt(fullFilePath);
		return fileName.lastIndexOf(".") >= 0 ? fileName.substring(0, fileName.lastIndexOf(".")) : fileName;
	}

	/**
	 * 获取路径的文件名包含路径不包含扩展名 c:/dir1/dir2/file1.txt => c:/dir1/dir2/file1
	 * 
	 * @author gk @date 2017-10-20 上午9:42:31
	 * @param fullFilePath
	 * @return
	 */
	public static String extractFileNamePath(String fullFilePath) {
		return fullFilePath.lastIndexOf(".") >= 0 ? fullFilePath.substring(0, fullFilePath.lastIndexOf(".")) : fullFilePath;
	}

	/**
	 * 获取文件名的扩展名
	 * 
	 * @author gk @date 2019年3月13日 下午2:43:11
	 * @return
	 */
	public static String getFileNameExt(String fileName) {
		return fileName.substring(fileName.lastIndexOf('.') + 1);
	}

	/**
	 * 删除目录（文件夹）以及目录下的文件
	 * 
	 * @param sPath 被删除目录的文件路径
	 * @return 目录删除成功返回true，否则返回false
	 */
	public static void deleteDirectory(String sPath) {
		// 如果sPath不以文件分隔符结尾，自动添加文件分隔符
		if (!StringUtils.endsWithAny(sPath, SEPARATOR)) {
			sPath = sPath + FileManager.SEPARATOR;
		}
		File dirFile = new File(sPath);
		// 如果dir对应的文件不存在，或者不是一个目录，则退出
		if (!dirFile.exists() || !dirFile.isDirectory()) {
			return;
		}
		// 删除文件夹下的所有文件(包括子目录)
		File[] files = dirFile.listFiles();
		if (files != null) {
			for (int i = 0; i < files.length; i++) {
				// 删除子文件
				if (files[i].isFile()) {
					deleteFile(files[i].getAbsolutePath());
				} // 删除子目录
				else {
					deleteDirectory(files[i].getAbsolutePath());
				}
			}
		}
		// 删除当前目录
		dirFile.delete();
	}

	/**
	 * 递归取到当前目录所有文件
	 * 
	 * @param dir 需获取的目录
	 * @return
	 */
	public static List<File> getFiles(String dir) {
		List<File> lstFiles = new ArrayList<File>();
		File file = new File(dir);
		File[] files = file.listFiles();
		if (files == null) {
			return lstFiles;
		}
		for (File f : files) {
			if (f.isDirectory()) {
				lstFiles.add(f);
				lstFiles.addAll(getFiles(f.getAbsolutePath()));
			} else {
				lstFiles.add(f);
			}
		}
		return lstFiles;
	}

	/**
	 * 递归取到当前目录所有文件 只有本地路径才允许调用该函数
	 * 
	 * @param url 需获取的路径
	 * @param filters 过滤正则表达式
	 * @return
	 * @throws MalformedURLException
	 */
	public static List<URL> getFiles(URL url, String filters) throws MalformedURLException {
		assert ("file".equals(url.getProtocol()));
		Pattern pattern = null;
		String fileFullName = "*.*";
		String fileType = ".*";
		String fileName = "*";
		if (fileFullName.equals(filters) || fileType.equals(filters) || fileName.equals(filters)) {
		} else {
			pattern = Pattern.compile(filters);
		}
		List<URL> lstFiles = new ArrayList<URL>();
		File file = new File(url.getFile());
		File[] files = file.listFiles();
		if (files == null) {
			return lstFiles;
		}
		for (File f : files) {
			if (pattern == null) {
				lstFiles.add(f.toURI().toURL());
				if (f.isDirectory()) {
					lstFiles.addAll(getFiles(f.toURI().toURL(), filters));
				}
			} else {
				String fpath = f.getPath().replace("\\", SEPARATOR);
				if (pattern.matcher(fpath).matches()) {
					lstFiles.add(f.toURI().toURL());
				}
				if (f.isDirectory()) {
					lstFiles.addAll(getFiles(f.toURI().toURL(), filters));
				}
			}

		}
		return lstFiles;
	}

	/***
	 * 目录拷贝
	 * @author licheng
	 * @date 2021-04-11
	 * @param srcDir
	 * @param destDir
	 * @throws IOException
	 */
	public static void copyDir(String srcDir, String destDir) throws IOException {
		File destFile = createDir(destDir);
		copyDir(new File(srcDir), destFile);
	}

	/***
	 * 目录拷贝
	 * @author licheng
	 * @date 2021-04-11
	 * @param srcFile
	 * @param tarFile
	 * @throws IOException
	 */
	public static void copyDir(File srcFile, File tarFile) throws IOException {
		FileUtils.copyDirectory(srcFile, tarFile);
	}

	/***
	 * 获取附件目录
	 * 
	 * @author licheng
	 * @date 2018年5月14日
	 * @return
	 */
	public static final File getWorkSpace() {
		if (workSpace == null) {
			String path = "";
			try {
				path = FileManager.getAppRealPath();
				// 通过Spring的ApplicationContext附件目录
				// path = FileUitls.getRealPath(path);
				// 如果无法获取,通过shiro获取上下文，获取附件目录
				if (StringUtils.isBlank(path)) {
					ServletRequest request = ((WebSubject) SecurityUtils.getSubject()).getServletRequest();
					path = ((HttpServletRequest) request).getSession().getServletContext().getRealPath(path);
				}
				workSpace = mkdir(path);
			} catch (Exception e) {
				workSpace = null;
			}
		}
		return workSpace;

	}

	/***
	 * 兼容Controller获取绝对路径问题
	 * 
	 * @author licheng
	 * @date 2018年7月27日
	 * @param request
	 * @return
	 */
	public static final File getWorkSpace(HttpServletRequest request) {
		String path = "";
		try {
			path = FileManager.getAppRealPath();
			path = request.getSession().getServletContext().getRealPath(path);
			workSpace = mkdir(path);
		} catch (Exception e) {
			workSpace = getWorkSpace();
		}
		return workSpace;
	}

	/***
	 * 本地目录操作：获取expSpace目录
	 * @author licheng
	 * @date 2021-04-11
	 * @return
	 */
	public static File getExpSpace() {
		if (expSpace == null || !expSpace.exists()) {
			expSpace = getSpace(getWorkSpace(), "expSpace");
		}
		return expSpace;
	}

	/** 本地目录操作：获取impSpace目录 */
	public static File getImpSpace() {
		if (impSpace == null || !impSpace.exists()) {
			impSpace = getSpace(getWorkSpace(), "impSpace");
		}
		return impSpace;
	}

	/* 本地目录操作：获取tempSpace目录 */
	public static File getTempSpace() {
		if (tempSpace == null || !tempSpace.exists()) {
			tempSpace = getSpace(getWorkSpace(), "tempSpace");
		}
		return tempSpace;
	}

	/** 本地目录操作：获取uploadSpace目录 */
	public static File getUploadSpace() {
		if (uploadSpace == null || !uploadSpace.exists()) {
			uploadSpace = getSpace(getWorkSpace(), "uploadSpace");
		}
		return uploadSpace;
	}

	/**
	 * 本地目录操作：在指定目录workSpace下获取名字为spaceName的文件夹; 如果文件夹不存在，则创建
	 * @author licheng
	 * @date 2021-04-11
	 * @param workSpace
	 * @param spaceName
	 * @return
	 */
	public static File getSpace(File workSpace, String spaceName) {
		File space = mkdir(workSpace, spaceName, true);
		if (space == null || !space.exists()) {
			return null;
		}
		return space;
	}

	/**
	 * 在临时文件夹tempSpace下,生成一个随机目录
	 * @author licheng
	 * @date 2021-04-11
	 * @return
	 */
	public static final File randomTempSpace() {
		return randomSpace(getTempSpace());
	}

	/**
	 * 在指定的目录下生成一个随机文件夹
	 * @author licheng
	 * @date 2021-04-11
	 * @param workSpace
	 * @return
	 */
	public static File randomSpace(File workSpace) {
		String spaceName = OgnlUtils.randomUpperCaseId();
		return mkdir(workSpace, spaceName, true);
	}

	/**
	 * 在指定的目录下生成文件夹,根据mkdir属性判断，是否需要强行创建文件夹
	 * @author licheng
	 * @date 2021-04-11
	 * @param parent
	 * @param name
	 * @param mkdir
	 * @return
	 */
	private static final File mkdir(File parent, String name, boolean mkdir) {
		File dir = new File(parent, name);
		if (!dir.exists() && mkdir) {
			dir.mkdirs();
		}
		return dir;
	}

	/**
	 * 获取一个目录，如果目录不存在，则创建
	 * 
	 * @author licheng
	 * @date 2018-12-22
	 * @param path
	 * @return
	 */
	private static final File mkdir(String path) {
		File f = new File(path);
		if (!f.exists()) {
			f.mkdirs();
		}
		return f;
	}

	/**
	 * 获取excel 模板的临时全路径
	 * 
	 * @author gk @date 2019年3月11日 下午2:35:25
	 * @return
	 */
	public static String getExcelTemplateRealPath() {
		return getAppRealPath() + "/filesres/excelTemplate/";
	}

	/**
	 * 获取系统的AppDir的本地全路径
	 * 
	 * @author gk @date 2017-9-24 下午2:02:13
	 * @return
	 */
	public static String getAppRealPath() {
		return getRealPath(getRelativeAppPath());

	}

	public static String getRelativeAppPath() {
		return "WEB-INF/static/";
	}

	public static final String getWebPath(String reativePath) {
		return StringUtils.removeEnd(getRelativeAppPath().replace("WEB-INF/", ""), SEPARATOR) + SEPARATOR + StringUtils.removeStart(reativePath, SEPARATOR);
	}

	public static String getSysoptRealPath(String reativePath) {
		String rootdir = "";
		if (StringUtils.isBlank(rootdir)) {
			return getAppDirRealPath(reativePath);
		}
		String serverPath = null;
		if (!StringUtils.endsWithAny(rootdir, SEPARATORS) && !StringUtils.startsWithAny(reativePath, SEPARATORS)) {
			serverPath = FileManager.formatWebPath(rootdir + SEPARATOR + reativePath);
		} else if (StringUtils.endsWithAny(rootdir, SEPARATORS) && StringUtils.startsWithAny(reativePath, SEPARATORS)) {
			reativePath = StringUtils.removeStart(reativePath, SEPARATOR);
			reativePath = StringUtils.removeStart(reativePath, "\\\\");
			reativePath = StringUtils.removeStart(reativePath, "\\");
			serverPath = FileManager.formatWebPath(rootdir + StringUtils.removeStart(reativePath, SEPARATOR));
		} else {
			serverPath = FileManager.formatWebPath(rootdir + reativePath);
		}
		return serverPath;
	}

	/**
	 * 获取系统的临时路径
	 * 
	 * @author gk @date 2018年9月19日 下午4:08:07
	 * @return
	 */
	public static String getAppTempRealPath() {

		String appDir = getAppRealPath();
		return appDir + SEPARATOR + "tmp";

	}

	/**
	 * 获取相对与appDataDir路径下的全路径
	 * 
	 * @author gk @date 2019年3月7日 上午9:57:00
	 * @param reativePath
	 * @return
	 */
	public static String getAppDirRealPath(String reativePath) {
		return StringUtils.removeEnd(getAppRealPath(), SEPARATOR) + SEPARATOR + StringUtils.removeStart(reativePath, SEPARATOR);
	}

	private static String infPath = "";

	/**
	 * 根据给定的相对目录获取绝对目录
	 * @author gk @date 2017-9-24 下午2:06:16
	 * @param reativePath 相对目录
	 * @return
	 */
	public static String getRealPath(String reativePath) {
		if ("".equals(infPath)) {
			WebApplicationContext webApplicationContext = (WebApplicationContext) FSContext.getApplicationContext();
			ServletContext servletContext = webApplicationContext.getServletContext();
			infPath = servletContext.getRealPath(SEPARATOR).replace("\\", SEPARATOR);
		}
		if (StringUtils.isBlank(reativePath)) {
			return infPath;
		}
		String serverPath = null;
		if (!StringUtils.endsWithAny(infPath, SEPARATORS) && !StringUtils.startsWithAny(reativePath, SEPARATORS)) {
			serverPath = FileManager.formatWebPath(infPath + SEPARATOR + reativePath);
		} else if (StringUtils.endsWithAny(infPath, SEPARATORS) && StringUtils.startsWithAny(reativePath, SEPARATORS)) {
			reativePath = StringUtils.removeStart(reativePath, SEPARATOR);
			reativePath = StringUtils.removeStart(reativePath, "\\\\");
			reativePath = StringUtils.removeStart(reativePath, "\\");
			serverPath = FileManager.formatWebPath(infPath + StringUtils.removeStart(reativePath, SEPARATOR));
		} else {
			serverPath = FileManager.formatWebPath(infPath + reativePath);
		}
		return serverPath;
	}

	/**
	 * 获取classpath的全路径
	 * 
	 * @author gk @date 2019年3月11日 下午2:46:55
	 * @return
	 */
	public static String getClassRealPath() {
		return getRealPath("WEB-INF/classes/");
	}

	/**
	 * 获取static的全路径
	 * 
	 * @author gk @date 2019年3月11日 下午2:46:55
	 * @return
	 */
	public static String getStaticRealPath() {
		return getRealPath("WEB-INF/static/");
	}

	/**
	 * 获取lib的全路径
	 * 
	 * @author gk @date 2019年3月11日 下午2:46:55
	 * @return
	 */
	public static String getLibRealPath() {
		return getRealPath("WEB-INF/lib/");
	}

	/**
	 * 获取view的全路径
	 * 
	 * @author gk @date 2019年3月11日 下午2:46:55
	 * @return
	 */
	public static String getViewRealPath() {
		return getRealPath("WEB-INF/view/");
	}

	/**
	 * 获取logs的全路径
	 * 
	 * @author gk @date 2019年3月11日 下午2:46:55
	 * @return
	 */
	public static String getLogsRealPath() {
		return getRealPath("WEB-INF/logs/");
	}

	/**
	 * 获取plugins的全路径
	 * 
	 * @author gk @date 2019年3月11日 下午2:46:55
	 * @return
	 */
	public static String getPluginsRealPath() {
		return getRealPath("WEB-INF/plugins/");
	}
}
